package view;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;

import controller.OrderController;
import model.Customer;
import model.CustomerList;
import model.InventoryList;
import model.Item;
import model.Order;
import model.OrderList;

/**********************************************************
 * Class: SimpleOrder
 * @author Joshua
 *
 * Description: The driver class for the SimpleOrder application.
 * Calls the GUI class or provides a text based interface.
 */

public class SimpleOrder {
	
	private static InventoryList inventory;
	private static OrderList orders;
	private static CustomerList customers;
	
	//the files to write to
	private static final String INVENTORY = "storage/inventoryList";
	private static final String ORDERS = "storage/orderList";
	private static final String CUSTOMERS = "storage/customerList";
	
	public static void main(String args[]){
		OrderController controller = new OrderController();
		
		//populate the lists
		initialize(controller);
		
		//begin interaction with the user
		Scanner input = new Scanner(System.in);
		String response;
		
		
		//main loop
		System.out.println("Greetings, what would you like to do?");
		while(true){
			System.out.println();
			System.out.println("1. Add a new customer.");
			System.out.println("2. Add a new item.");
			System.out.println("3. Add a stock for an item.");
			System.out.println("4. Place an order.");
			System.out.println("5. Display inventory.");
			System.out.println("6. Display orders.");
			System.out.println("7. Display customers.");
			System.out.println("8. Save data.");
			System.out.println("9. Quit");
			response = input.nextLine();
			System.out.println();

			//decide what to do
			switch(response){
			case("1") :{
				addCustomer(input);
				break;
			}	
			case("2") : {
				addItem(input);
				break;
			}
			case("3") : {
				addStock(input);
				break;
			}
			case("4") : {
				placeOrder(input);
				break;
			}
			case("5") : {
				showInventory();
				break;
			}
			case("6") : {
				showOrders();
				break;
			}
			case("7") : {
				showCustomers();
				break;
			}
			case("8") : {
				save(controller);
				break;
			}
			case("9") : {
				System.exit(0);
				break;
			}
			default : {
				System.out.println("Please enter a valid selection.");
				break;
			}
			}
		}
		
	}
	
	/**
	 * initialize
	 * @param an OrderController
	 * description: loads any saved inventory, customer, or order
	 * data.
	 */
	private static void initialize(OrderController controller){
		try{
			inventory = controller.initInventory(INVENTORY);
		}catch(FileNotFoundException fnf){
			System.out.println("Warning: The save file "+INVENTORY+" does not exist.");
			System.out.println("No pre-existing inventory data will be loaded.");
			inventory = new InventoryList();
		}try{
			orders = controller.initOrders(ORDERS);
		}catch(FileNotFoundException fnf){
			System.out.println("Warning: The save file "+ORDERS+" does not exist.");
			System.out.println("No pre-existing order data will be loaded.");
			orders = new OrderList();
		}try{
			customers = controller.initCustomers(CUSTOMERS);
		}catch(FileNotFoundException fnf){
			System.out.println("Warning: The save file "+CUSTOMERS+" does not exist.");
			System.out.println("No pre-existing order data will be loaded.");
			customers = new CustomerList();
		}
		
	}//end initialize
	
	/**
	 * addCustomer
	 * @param an input scanner
	 * 
	 * description: creates a Customer instance and adds it to the
	 * list of customers.
	 */
	private static void addCustomer(Scanner input){
		String name;
		String custid;
		String address;
		
		System.out.println("Please enter the customer's name:");
		name = input.nextLine();
		//error checking
		while(name.isEmpty()){
			System.out.println("Name cannot be empty. Please enter a valid name:");
			name = input.nextLine();
		}
		System.out.println("Please enter the customer's address:");
		address = input.nextLine();
		//error checking
		while(address.isEmpty()){
			System.out.println("Address cannot be empty. Please enter a valid address:");
			address = input.nextLine();
		}
		System.out.println("Please create an id for this customer:" +
				" (Should be 4 digits in length)");
		custid = input.nextLine();
		//error checking
		while(custid.length() != 4){
			System.out.println("ID must contain 4 characters. Please enter a valid address:");
			custid = input.nextLine();
		}
		
		Customer customer = new Customer(custid, name, address);
		customers.add(customer);
		System.out.println("Customer added!");
	}//end addCustomer
	
	/**
	 * addItem
	 * @param an input Scanner
	 * 
	 * description: creates an Item instance from user input and adds
	 * it to the inventory.
	 */
	private static void addItem(Scanner input){
		String name;
		String itemid;
		int quantity;

		System.out.println("Please enter the name of the item:");
		name = input.nextLine();
		//error checking
		while(name.isEmpty()){
			System.out.println("Name cannot be empty. Please enter a valid name:");
			name = input.nextLine();
		}
		System.out.println("Please enter the amount of items:");
		
		while(true){
			try{
				quantity = Integer.parseInt(input.nextLine());
				break;
			}catch(NumberFormatException nfe){ //the user did not enter a valid number
				System.out.println("Quantity must be a valid integer. Please enter a valid number of items to order:");
			}
		}
		
		System.out.println("Please create an id for this item:" +
				" (Should be 4 digits in length)");
		itemid = input.nextLine();
		//error checking
		while(itemid.length() != 4){
			System.out.println("ID must contain 4 characters. Please enter a valid address:");
			itemid = input.nextLine();
		}

		Item item = new Item(itemid, name, quantity);
		inventory.put(itemid, item);
		System.out.println("Item added!");
	}//end addItem
	
	/**
	 * addStock
	 * @param an input Scanner
	 * 
	 * description: locates an item in the inventory and adds a 
	 * user specified amount to that item's quantity.
	 */
	private static void addStock(Scanner input){
		String itemid;
		int quantity;

		System.out.println("Please enter the id of the item:");
		itemid = input.nextLine();
		System.out.println("How much stock would you like to add?");
		quantity = Integer.parseInt(input.nextLine());
		
		Item item = inventory.get(itemid);		
		if(item == null){
			//the item does not yet exist in the inventory
			System.out.println("Invalid item id. This item can" +
					"be created and placed in the inventory by");
			System.out.println("selecting the \"add item\" option.");
		}else{
			item.setQuantity(item.getQuantity() + quantity);
			inventory.put(itemid, item);
			System.out.println("Stock successfully added!");
		}
	}//end addStock
	
	/**
	 * placeOrder
	 * @param an input Scanner
	 * 
	 * description: Instantiates an new Order based on user input and
	 * adds it to the list of Orders.
	 */
	private static void placeOrder(Scanner input){
		String custid;
		String itemid;
		String name;
		String date;
		int quantity;

		System.out.println("To start a new order, please enter a valid " +
				"customer id:");
		custid = input.nextLine();
		
		//get the customer
		Customer customer = customers.get(custid);

		while(customer == null){
			//the user didn't enter a valid customer id
			System.out.println("Error: The specified customer does not" +
					"exist in our recods.");
			System.out.println("Please enter a valid customer id:");
			custid = input.nextLine();
			customer = customers.get(custid);
		}
		
		System.out.println("Please enter the date the order will be placed: (mm/dd/yyyy");
		date = input.nextLine();
		
		
		Order order = new Order(customer, date);

		//prompt the user to add items until the user 
		//enters nothing
		System.out.print("Enter an item id to add an item to the order ");
		System.out.println("(Just press enter when finished adding items):");
		itemid = input.nextLine();
		
		//loop until the user enters nothing
		while(!itemid.isEmpty()){
			try{
				//lookup the item id to get the name
				name = inventory.get(itemid).getName();
				
				System.out.println("How many would you like to order?");
				while(true){
					try{
						quantity = Integer.parseInt(input.nextLine());
						break;
					}catch(NumberFormatException nfe){ //the user did not enter a valid number
						System.out.println("Quantity must be a valid integer. Please enter a valid number of items to order:");
					}
				}
				
				order.add(new Item(itemid, name, quantity));
				System.out.println("Item added! Next item?");
			}catch(NullPointerException np){
				//the item did not exist in the inventory
				System.out.println("Error: That item does not exist in" +
						"our inventory.");
				System.out.println("Please enter a valid item id:");
			}
			
			itemid = input.nextLine();
		}
		
		System.out.println("Order complete!");
		orders.add(order);
	}//end placeOrder
	
	/**
	 * showCustomers
	 * description: displays a formatted list of customers containing
	 * their ID's and details.
	 */
	private static void showCustomers(){
		System.out.println("--List of Customers--");
		Iterator<Customer> iterator = customers.iterator();
		
		while(iterator.hasNext()){
			Customer current = iterator.next();
			System.out.println(current.getCustId()+":");
			System.out.println("\tName: "+current.getName());
			System.out.println("\tAddress: "+current.getAddress());
		}
	}
	
	/**
	 * showInventory
	 * description: displays a list of all items in the inventory.
	 */
	private static void showInventory(){
		System.out.println("--Current Inventory--");
		Set<String> keyset = inventory.keySet();
		Iterator<String> iterator = keyset.iterator();

		while(iterator.hasNext()){
			String key = iterator.next();
			
			Item current = inventory.get(key);
			System.out.println(current.getPartNum()+":");
			System.out.println("\tItem: "+current.getName());
			System.out.println("\tQuantity: "+current.getQuantity());
		}
	}
	
	/**
	 * showOrders
	 * description: displays a list of all orders placed.
	 */
	private static void showOrders(){
		System.out.println("--List of Orders--");
		Iterator<Order> iterator = orders.iterator();

		while(iterator.hasNext()){
			Order current = iterator.next();
			System.out.print("Order placed by ");
			System.out.println(current.getCustomer().getName()+":");
			System.out.println("\tDate: "+current.getDate());
			System.out.println("\tItems: (part number, quantity)");
			Iterator<Item> items = current.iterator();
			while(items.hasNext()){
				Item currItem = items.next();
				System.out.println("\t\t"+currItem.getPartNum()+", "+
						currItem.getQuantity());
			}
		}
	}
	
	/**
	 * save
	 * @param an OrderController
	 * 
	 * description: serializes the inventory, customer list, and order
	 * list and writes them to a file.
	 */
	private static void save(OrderController controller){
		try {
			controller.save(inventory, INVENTORY);
		} catch (FileNotFoundException e) {
			System.out.println("Error: Unable to save inventory to"+
					INVENTORY+".");
			System.out.println("Please make sure the file exists.");
		} catch (IOException e) {
			e.printStackTrace();
		}try {
			controller.save(orders, ORDERS);
		} catch (FileNotFoundException e) {
			System.out.println("Error: Unable to save orders to"+
					ORDERS+".");
			System.out.println("Please make sure the file exists.");
		} catch (IOException e) {
			e.printStackTrace();
		}try {
			controller.save(customers, CUSTOMERS);
		} catch (FileNotFoundException e) {
			System.out.println("Error: Unable to save customers to"+
					CUSTOMERS+".");
			System.out.println("Please make sure the file exists.");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
